// src/mem_io.rs
use core::arch::asm;

/// 写入 u8 到指定内存地址
pub unsafe fn write_u8(address: *mut u8, value: u8) {
    asm!(
        "mov byte ptr [{0}], {1}",
        in(reg) address,
        in(reg_byte) value,
        options(nostack, preserves_flags)
    );
}

/// 写入 u16 到指定内存地址
pub unsafe fn write_u16(address: *mut u16, value: u16) {
    asm!(
        "mov word ptr [{0}], {1:x}", // l 低8位，h 高8位 x 16位 e 32位 r 64位
        in(reg) address,
        in(reg) value,
        options(nostack, preserves_flags)
    );
}

/// 写入 u32 到指定内存地址
pub unsafe fn write_u32(address: *mut u32, value: u32) {
    asm!(
        "mov dword ptr [{0}], {1:e}",
        in(reg) address,
        in(reg) value,
        options(nostack, preserves_flags)
    );
}

/// 写入 u64 到指定内存地址
pub unsafe fn write_u64(address: *mut u64, value: u64) {
    asm!(
        "mov qword ptr [{0}], {1:r}",
        in(reg) address,
        in(reg) value,
        options(nostack, preserves_flags)
    );
}

/// 从内存地址读取 u8
pub unsafe fn read_u8(address: *const u8) -> u8 {
    let value: u8;
    asm!(
        "mov {}, byte ptr [{}]",
        out(reg_byte) value,
        in(reg) address,
        options(nostack, preserves_flags)
    );
    value
}

/// 从内存地址读取 u16
pub unsafe fn read_u16(address: *const u16) -> u16 {
    let value: u16;
    asm!(
        "mov {0:x}, word ptr [{1}]",
        out(reg) value,
        in(reg) address,
        options(nostack, preserves_flags)
    );
    value
}

/// 从内存地址读取 u32
pub unsafe fn read_u32(address: *const u32) -> u32 {
    let value: u32;
    asm!(
        "mov {0:e}, dword ptr [{1}]",
        out(reg) value,
        in(reg) address,
        options(nostack, preserves_flags)
    );
    value
}

/// 从内存地址读取 u64
pub unsafe fn read_u64(address: *const u64) -> u64 {
    let value: u64;
    asm!(
        "mov {0:r}, qword ptr [{1}]",
        out(reg) value,
        in(reg) address,
        options(nostack, preserves_flags)
    );
    value
}

/// 写入 VGA 字符到指定地址 (优化版本)
pub fn write_vga_char(address: *mut u16, value: u16) {
    unsafe {
        write_u16(address, value);
    }
}

/// 从 VGA 地址读取字符
pub fn read_vga_char(address: *const u16) -> u16 {
    unsafe {
        read_u16(address)
    }
}